﻿

namespace Mangosoft.DiceCopy.Application.MainBoundedContext.JobHuntingModule.Services {

    using System.Collections.Generic;
    using System.Linq;
    using Mangosoft.DiceCopy.Application.MainBoundedContext.DTO;
    using Mangosoft.DiceCopy.Application.Seedwork;
    using Mangosoft.DiceCopy.Domain.MainBoundedContext.Aggregates.AdvertisingAgg;
    using Mangosoft.DiceCopy.Domain.MainBoundedContext.Aggregates.JobseekerAgg;
    using Mangosoft.DiceCopy.Domain.MainBoundedContext.Aggregates.NewsAgg;
    using Mangosoft.DiceCopy.Domain.MainBoundedContext.Aggregates.ResumeAgg;
    using Mangosoft.DiceCopy.Infrastructure.Crosscutting.Validator;

    public class JobHuntingAppService : IJobHuntingAppService {

        #region Fields
        private readonly INewsRepository _newsRepository;
        private readonly IJobseekerRepository _jobseekerRepository;
        private readonly IAdvertisingRepository _advertisingRepository;
        private readonly IResumeRepository _resumeRepository;

        #endregion

        #region Ctors
        public JobHuntingAppService(IJobseekerRepository jobseekerRepository,
            INewsRepository newsRepository,
            IAdvertisingRepository advertisingRepository,
            IResumeRepository resumeRepository) {
            _jobseekerRepository = jobseekerRepository;
            _newsRepository = newsRepository;
            _advertisingRepository = advertisingRepository;
            _resumeRepository = resumeRepository;
        }
        #endregion

        public List<NewsDTO> FindNewsByChannel(int channel) {
            var news = _newsRepository.AllMatching(NewsSpecifications.NewsByChannel(channel) & NewsSpecifications.EnabledNews());

            if (news != null && news.Any()) {
                return news.ProjectedAsCollection<NewsDTO>();
            }

            return null;
        }

        public List<NewsDTO> FindNews() {
            var news = _newsRepository.GetAll();

            if (news != null && news.Any()) {
                return news.ProjectedAsCollection<NewsDTO>();
            }

            return null;
        }

        public List<AdvertisingDTO> FindAdvertisingByBlock(int blockcode) {
            var ads = _advertisingRepository.AllMatching(AdvertisingSpecifications.AdvertingsByBlock(blockcode));

            if (ads != null && ads.Any()) {
                return ads.ProjectedAsCollection<AdvertisingDTO>();
            }

            return null;
        }

        public ResumeDTO AddNewResume(ResumeDTO resume) {
            var jobseeker = _jobseekerRepository.Get(resume.JobseekerId);

            if (jobseeker != null) {
                var newResume = CreateNewResume(resume, jobseeker);

                // save
                SaveResume(newResume);              

                return newResume.ProjectedAs<ResumeDTO>();
            }
            return null;
        }

        private Resume CreateNewResume(ResumeDTO dto, Jobseeker associatedJobseeker) {
            Resume newResume = ResumeFactory.CreateResume(
                associatedJobseeker,
                dto.Name,
                dto.ResumeNumber,
                dto.FirstName,
                dto.LastName,
                dto.AvatarId,
                dto.Phone,
                dto.Mobile,
                dto.ProvinceCode,
                dto.CityCode,
                dto.Address,
                dto.Zip,
                dto.Gender,
                dto.Birthdate,
                dto.EducationLevelCode,
                dto.YearsExperienceCode,
                dto.QQ,
                dto.Blog,
                dto.SNS1,
                dto.SNS2,
                dto.SNS3,
                dto.Biography,
                dto.Tags,
                dto.IndustryCode,
                dto.DesiredPosition,
                dto.PositionTypeCode,
                dto.AnnualPayCode,
                dto.PreferredLocations,
                dto.WillingToTravelCode,
                dto.WillingToRelocate,
                dto.WillingToTelecommute,
                dto.CanStartCode,
                dto.FromThirdParty,
                dto.ResumeType,
                dto.PrivacyStatus,
                dto.Integrity 
        );

            if (dto.Educations != null) {
                foreach (var edu in dto.Educations) {
                    newResume.AddEducationEntry(
                        edu.SchoolTypeCode,
                        edu.School,
                        edu.StartYear,
                        edu.EndYear,
                        edu.College,
                        edu.MajorCode,
                        edu.EducationLevelCode,
                        edu.Notes,
                        edu.ProvinceCode,
                        edu.CityCode);
                }
            }

            return newResume;
        }

        void SaveResume(Resume resume) {
            var entityValidator = EntityValidatorFactory.CreateValidator();

            //if entity is valid save. 
             if (entityValidator.IsValid(resume)){
                 _resumeRepository.Add(resume);
                 _resumeRepository.UnitOfWork.Commit();
             }
        }
    }
}
